<!--
 * @Description: 树组件，可编辑
 * @Author: 
 * @Date:
 * @LastEditors  : 
 * @LastEditTime : 
 -->
<template>
  <!-- :current-node-key="treeData[0][treeConfig.id]" -->
  <el-scrollbar>
    <el-tree
      class="data_tree"
      :data="treeData"
      :lazy="lazy"
      :load="loadNodeFun"
      :show-checkbox="showCheckbox"
      :default-expand-all="expandAll"
      :highlight-current="!noHighNode"
      :expand-on-click-node="clickNodeExpand"
      :props="treeConfig"
      :check-on-click-node="checkOnClickNode"
      :node-key="treeConfig.id"
      :default-expanded-keys="defaultExpandedKeys"
      @node-click="nodeClick"
      @node-contextmenu="rightClick"
      @check="getCheckNode"
      @node-expand="nodeExpand"
      @node-collapse="nodeCollapse"
      ref="tree"
    >
      <span
        class="custom-tree-node"
        style="position: relative"
        slot-scope="{ node, data }"
      >
        <span class="el-icon-s-home">{{ node.label }}</span>
        <transition name="fade">
          <div
            class="tree_tip"
            id="tree_tip"
            ref="treeTip"
            style="top: ; left: "
            v-if="data[treeConfig.id] == currentIndex[treeConfig.id]"
          >
            <span @click.stop="() => append(data)">新增子节点</span>
            <span @click.stop="() => edit(data)">编辑名称</span>
            <span @click.stop="() => remove(data)">删除该节点</span>
          </div>
        </transition>
      </span>
    </el-tree>
  </el-scrollbar>
</template>

<script>
export default {
  props: {
    treeData: {
      type: Array,
      default: () => [],
    },
    // 懒加载
    lazy: {
      type: Boolean,
      default: false,
    },
    // 懒加载方法
    loadNodeFun: {
      type: Function,
    },
    // 是否右键事件
    noConfig: {
      type: Boolean,
      default: false,
    },
    // 树配置
    treeConfig: {
      type: Object,
      default: () => {},
    },
    // 高亮选中节点
    noHighNode: {
      type: Boolean,
      default: false,
    },
    // 显示复选框
    showCheckbox: {
      type: Boolean,
      default: false,
    },
    // 默认展开全部
    expandAll: {
      type: Boolean,
      default: false,
    },
    // 点击节点前的图标才展开，false 点击图标展开 true点击节点展开
    clickNodeExpand: {
      type: Boolean,
      default: false,
    },
    // 点击节点时勾选节点，复选框下才生效
    checkOnClickNode: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      currentIndex: {},
      defaultExpandedKeys: [],
    };
  },
  watch: {
    treeData: {
      handler() {
        this.$nextTick(() => {
          if (this.treeData.length > 0)
            this.$refs.tree.setCurrentNode(this.treeData[0]);
        });
      },
      immediate: true,
    },
  },
  // 指定组件上的v-model用$emit什么事件触发，默认input
  model: {
    event: "node",
  },
  mounted() {
    console.log(this.$options);
    console.log(this.$data)
  },
  methods: {
    // 右键弹出菜单
    rightClick(event, node) {
      window.clearInterval(this.treeMenu);
      if (this.noConfig) return;
      this.currentIndex = node;
      this.$nextTick(() => {
        this.$refs.treeTip.style.left = event.clientX + "px";
        if (window.innerHeight - event.clientY < 150) {
          this.$refs.treeTip.style.top = event.clientY - 95 + "px";
        } else {
          this.$refs.treeTip.style.top = event.clientY + "px";
        }
      });
      // 600ms反应时间，保证右键弹出框不会因为鼠标移开而马上消失
      this.treeMenu = window.setTimeout(() => {
        document.onmousemove = (e) => {
          let left = document.getElementById("tree_tip").offsetLeft;
          let width = document.getElementById("tree_tip").offsetWidth;
          let top = document.getElementById("tree_tip").offsetTop;
          let height = document.getElementById("tree_tip").offsetHeight;
          if (
            e.clientX < left - 5 ||
            e.clientX > left + width + 5 ||
            e.clientY < top - 5 ||
            e.clientY > top + height + 5
          ) {
            document.onmousemove = null;
            this.currentIndex = {};
          }
        };
      }, 600);
    },
    // 新增节点
    append(data) {
      this.$emit("append", data);
    },
    // 编辑节点
    edit(data) {
      this.$emit("edit", data);
    },
    // 移除节点
    remove(data) {
      this.$confirm("确认删除?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        this.$emit("remove", data);
      });
    },
    // 点击节点
    nodeClick(data) {
      this.$emit("node", data);
      document.onmousemove = null; // 防止事件未清除
    },
    // 复选框点击，获取节点
    getCheckNode(node, checkedNodes) {
      // console.log(node);//当前点击的复选框节点
      // console.log(checkedNodes); //checkedNodes、checkedKeys、halfCheckedNodes、halfCheckedKeys 四个属性
      this.$emit("checkNode", checkedNodes);
    },
    // 设置节点选中 回显
    setCheckNodeByKeys(keys) {
      this.$refs.tree.setCheckedKeys([]); //先清空选中状态
      keys.forEach((i, n) => {
        var node = this.$refs.tree.getNode(i);
        if (node.isLeaf) this.$refs.tree.setChecked(node, true);
      });
    },
    // 获取选中节点 getCheckedNodes getHalfCheckedNodes//getCheckedKeys getHalfCheckedKeys
    getCheckedNodesByKeys() {
      return [
        ...this.$refs.tree.getCheckedKeys(),
        ...this.$refs.tree.getHalfCheckedKeys(),
      ];
    },
    // 节点展开时触发
    nodeExpand(data, node, event) {
      this.defaultExpandedKeys.push(data[this.treeConfig.id]);
    },
    // 节点关闭时始触发
    nodeCollapse(data, node, event) {
      this.defaultExpandedKeys = this.defaultExpandedKeys.filter(
        (v) => v != data[this.treeConfig.id]
      );
    },
  },
};
</script>
<style lang="scss" >
/* 解决使用el-scrollbar不出现横向滚动条*/
.el-tree {
  display: inline-block;
  min-width: 100%;
}

.data_tree {
  height: 100%;
  overflow: auto;
  .el-tree-node__content {
    height: 40px;
  }
  .fade-enter-active,
  .fade-leave-active {
    transition: opacity 0.4s;
  }
  .fade-enter,
  .fade-leave-to {
    opacity: 0;
  }
  &.el-tree--highlight-current
    .el-tree-node.is-current
    > .el-tree-node__content {
    background-color: teal !important;
    color: #fff;
  }
  .el-tree-node__content {
    &:hover {
      background: deeppink;
    }
  }
  .el-tree-node:focus > .el-tree-node__content {
    background-color: orange;
  }
  /* 菜单 */
  .tree_tip {
    color: #666;
    position: fixed;
    background: #fff;
    display: flex;
    flex-direction: column;
    border-radius: 2px;
    z-index: 11;
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.3);
    span {
      height: 32px;
      line-height: 32px;
      padding: 0 20px;
      border-radius: 2px;
      transition: all 0.5s;
    }
    span:hover {
      background: #0e3d9c;
      color: #fff;
    }
  }
}
</style>
